home *** CD-ROM | disk | FTP | other *** search
- /* sio.c
-
-
- Serial I/O for rz/sz
-
-
- Copyright (c) 1986 Stuart Lynne
-
- June 1986
-
- Modified for Think C
-
- Sak Wathanasin 1989
-
- Portions Copyright ⌐ David Platt, 1992, 1991. All Rights Reserved
- Worldwide.
-
- */
- #include "sio.h"
-
- #include <stdio.h>
- #ifndef THINK_C
- #include <pb.h>
-
- #include <osutil.h>
-
- /* #include <max/macglobals.h> */
- #include <max/debug.h>
- #include <max/asc.h>
- #else THINK_C
- # include "dcp.h"
- #endif THINK_C
-
- #ifndef FALSE
- # define FALSE 0
- #endif FALSE
- #ifndef TRUE
- # define TRUE 1
- #endif TRUE
-
- #ifdef Upgrade
- static int g_setting;
- #endif Upgrade
-
- struct SIOPort curPort={0};
-
- #ifdef DOASYNC
-
- static struct async_write *asyncout;
- static int async_head, async_tail, async_pending;
- static int allowInterrupts = FALSE;
- static int interruptOccurred = FALSE;
- static int sleepLimit = 3;
-
- #endif
-
- #define baud38400 1
-
- struct {
- unsigned int baudr;
- int speedcode;
- } speeds[] = {
- 300, baud300,
- 600, baud600,
- 1200, baud1200,
- 2400, baud2400,
- 4800, baud4800,
- 9600, baud9600,
- 19200, baud19200,
- 38400, baud38400,
- 57600, baud57600,
- 0,
- };
-
- static char otherIn[] = "\p.?In";
- static char otherOut[] = "\p.?Out";
-
- static unsigned int
- getspeed(code)
- {
- register n;
-
- for (n=0; speeds[n].baudr; ++n)
- if (speeds[n].speedcode == code)
- return speeds[n].baudr;
- return -1;
- }
-
-
- static unsigned
- getbaud(code)
- char *code; {
- register n;
- register long int Baudrate;
-
- Baudrate = atol(code);
-
- for(n=0 ; speeds[n].baudr ; ++n)
- if(speeds[n].baudr == Baudrate)
- return(speeds[n].speedcode);
- return -1;
- }
-
-
-
- SIOInit ( whichport, speed )
- char * whichport;
- char * speed;
- {
- char i;
- SerShk handshake;
- int setting, baudCode, speedVal;
- int err;
- long int bytes;
-
- /* fprintf( stderr, "sioinit %s %s\n", whichport, speed ); /* */
-
- if (
- strncmp( whichport, ".a", 2 ) == 0 ||
- strncmp( whichport, "a",1 ) == 0 ||
- strcmp( whichport, "modem") == 0
- )
- {
- curPort.in = AIN;
- curPort.out = AOUT;
- }
- else if (
- strncmp( whichport, ".b", 2 ) == 0 ||
- strncmp( whichport, "b", 1 ) == 0 ||
- strcmp( whichport, "printer") == 0
- )
- {
- curPort.in = BIN;
- curPort.out = BOUT;
- }
- else if (strlen(whichport) == 1 && whichport[0] >= 'c' && whichport[0] <= 'z') {
- otherIn[2] = otherOut[2] = whichport[0];
- curPort.in = otherIn;
- curPort.out = otherOut;
- } else if (strlen(whichport) == 2 && whichport[0] == '.' && whichport[1] >= 'c' && whichport[1] <= 'z') {
- otherIn[2] = otherOut[2] = whichport[1];
- curPort.in = otherIn;
- curPort.out = otherOut;
- } else
- return( -1 );
-
- baudCode = getbaud(speed);
- if (baudCode == -1) {
- fprintf(stderr, "Baud rate %s is not supported or not recognized\n", speed);
- return (-1);
- }
-
- speedVal = getspeed(baudCode);
-
- if (speedVal <= 9600) {
- sleepLimit = 3;
- } else if (speedVal < 57600) {
- sleepLimit = 1;
- } else {
- sleepLimit = 0;
- }
-
- if ((err = OpenDriver ( (StringPtr)curPort.in, &curPort.refin )) !=0 ) {
- fprintf( stderr, "Err: %d\n", err);
- #ifdef DEBUG
- debugMsg ( ctop( curPort.in ) );
- #endif
- SysBeep (20);
- return( -1 );
- }
-
-
- if ((err=OpenDriver ( (StringPtr)curPort.out, &curPort.refout )) !=0 ) {
- fprintf( stderr, "Err: %d\n", err);
- #ifdef DEBUG
- debugMsg ( ctop( curPort.out ) );
- #endif
- SysBeep (20);
- return( -1 );
- }
-
- SIOHandshake( FALSE, FALSE, FALSE, XON, XOFF );
- SIOSetting( speed, noParity, stop10, data8 );
-
- #ifdef DOASYNC
-
- bytes = BUFFERS * sizeof (struct async_write);
-
- asyncout = (struct async_write *) NewPtr(bytes);
- if (asyncout) {
- memset(asyncout, 0, bytes);
- }
- async_head = async_tail = 0;
- allowInterrupts = interruptOccurred = FALSE;
-
- #endif
-
- return( 0 );
- }
-
- SIOSpeed( speed )
- char * speed;
- {
- SIOSetting( speed, curPort.parity, curPort.stopbits, curPort.databits );
- }
-
- SIOHandshake ( fInx, fXOn, fCTS, xOn, xOff )
- {
- int err;
-
- curPort.handshake.fInX = fInx;
- curPort.handshake.fXOn = fXOn;
- curPort.handshake.fCTS = fCTS;
-
- curPort.handshake.xOn = xOn;
- curPort.handshake.xOff = xOff;
- /* handshake.fXOn = TRUE; */
-
- curPort.handshake.errs = 0;
- curPort.handshake.evts = 0;
-
- if ((err=SerHShake (curPort.refin, &curPort.handshake ))!=0 ) {
- fprintf( stderr, "Err: %d\n", err);
- #ifdef DEBUG
- debugMsg ("\PSerHShake error");
- #endif
- SysBeep (20);
- }
- }
-
- SIOSetting( speed, parity, stopbits, databits )
- char * speed;
- {
- int err;
- int setting;
-
- curPort.baud = getbaud(speed);
- curPort.parity = parity;
- curPort.stopbits = stopbits;
- curPort.databits = databits;
-
- setting = curPort.baud + parity + stopbits + databits;
- #ifdef Upgrade
- /* store current settings in a global area */
- g_setting = setting;
- #endif Upgrade
-
- if ((err=SerReset(curPort.refin, setting))!=0 ) {
- fprintf( stderr, "Err: %d\n", err);
- #ifdef DEBUG
- debugMsg ("\PSerReset error");
- #endif
- SysBeep (20);
- }
- }
-
- SIOInBuffer ( buf, size )
- char * buf;
- int size;
- {
- curPort.inbuffer = buf;
- curPort.insize = size;
- SerSetBuf( curPort.refin, buf, size );
- }
-
- SIOOutBuffer ( buf, size )
- char * buf;
- int size;
- {
- curPort.outbuffer = buf;
- curPort.outsize = size;
- SerSetBuf( curPort.refout, buf, size );
- }
-
-
- SIOClose ( dtr )
- {
- CntrlParam SIOpb;
-
- long count;
-
- if ( dtr != 0 && curPort.refin != 0) {
- /* drop DTR */
- SIOpb.ioCompletion = NULL;
- SIOpb.ioRefNum = curPort.refin;
- SIOpb.csCode = 18;
- PBControl ((ParmBlkPtr)&SIOpb, FALSE);
- }
-
- SIOInBuffer( NULL, 0 );
- SIOOutBuffer( NULL, 0 );
- if (curPort.refin != 0) CloseDriver( curPort.refin );
- if (curPort.refout != 0)CloseDriver( curPort.refout );
- if (asyncout) {
- DisposPtr(asyncout);
- asyncout = NULL;
- }
- async_head = async_tail = async_pending = 0;
- curPort.refin = curPort.refout = 0;
- }
-
-
- sfflushout ()
- {
- }
-
- SIOSetFlowCtl(flag)
- int flag;
- {
- SerShk flowRec;
- flowRec.fXOn = flag;
- flowRec.fInX = flag;
- flowRec.fCTS = 0; /* bad juju to try... input handshake might be DTR */
- flowRec.xOn = 0x11;
- flowRec.xOff = 0x13;
- flowRec.errs = flowRec.evts = 0;
- SerHShake(curPort.refin, &flowRec);
- SerHShake(curPort.refout, &flowRec);
- }
-
- SIOAllowInterrupts(flag)
- int flag;
- {
- int oldFlag;
- oldFlag = allowInterrupts;
- allowInterrupts = flag;
- interruptOccurred &= flag;
- return oldFlag;
- }
-
- SIOInterrupt()
- {
- interruptOccurred = TRUE;
- }
-
- SIOPurge ()
- { /*
- char ch;
-
- while (sread (&ch, 1, 1) == 1);
-
- */
- (void) KillIO(curPort.refin);
- (void) KillIO(curPort.refout);
- }
-
- SIOPutchar ( ch )
- char ch;
- {
- /*fprintf(stderr, "<%02x>", ch);*/
- return( putu ( &ch, 1, curPort.refout ) );
- }
-
- SIOWrite ( buf, count )
- char * buf;
- int count;
- {
- return( putu (buf, count, curPort.refout) );
- }
-
- int SIOAvail()
- {
- long int count;
- (void)SerGetBuf(curPort.refin, &count);
- return count;
- }
-
-
- SIOWStr ( st )
- char * st;
- {
- return( putu (st, strlen(st), curPort.refout) );
- }
-
- #define Ticks (*(long *) 0x16a)
-
-
- /* timeout is in tenths of a second */
- int SIORead ( byt, mincount, maxcount, tenths )
- char * byt;
- int mincount;
- int maxcount;
- long int tenths;
- {
- long timea;
- short actCount;
-
- int i;
-
- timea = Ticks;
- tenths *= 6;
- /* fprintf (stderr, "Read m= %d T= %ld", maxcount, Ticks );/**/
- do {
- actCount = getn (byt, mincount, maxcount, curPort.refin );
-
- if (actCount > 0) {
- /* fprintf (stderr, " OK: %d\n", actCount);/**/
- return actCount;
- }
-
- if (allowInterrupts && interruptOccurred) {
- return -1;
- }
-
- } while ((long)(Ticks - timea) < tenths);
-
- /* fprintf (stderr, " Timed out: t= %d\n T:%ld", tenths, Ticks );/**/
- return -1;
- }
-
- srdchk ()
- {
- long count;
-
- (void)SerGetBuf(curPort.refin, &count);
- if (count >= 1)
- return TRUE;
- else
- return FALSE;
- }
-
- #ifdef BREAK
- ssendbrk(bnulls) {
- int setting;
-
- # ifdef Upgrade
- setting = baud300 + noParity + stop10 + data8;
- # else Upgrade
- setting = curPort.baud + noParity + stop10 + data8;
- # endif Upgrade
-
- if(SerReset(curPort.refin, setting)) {
- # ifdef DEBUG
- debugMsg("\PSerReset error");
- # endif
- SysBeep(20);
- }
-
- swrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", bnulls*2);
-
- # ifdef Upgrade
- setting = g_setting;
- # else Upgrade
- setting = curPort.baud + noParity + stop10 + data8;
- # endif Upgrade
-
- if(SerReset(curPort.refin, setting)) {
- # ifdef DEBUG
- debugMsg("\PSerReset error");
- # endif
- SysBeep(20);
- }
- return;
- }
- #endif BREAK
-
-
- /* Fill array *cp with characters from serial buffer, starting
- at 0, until cmax. Return actual chars read. Don't read unless
- at least cmin are available.
- */
- int getn ( cp, cmin, cmax, refin )
- char *cp;
- register int cmax, cmin;
- register short refin;
- {
- ParamBlockRec SIOpb;
- register ParmBlkPtr pbp = &SIOpb;
-
- long count;
- int firstTry = TRUE;
-
- /* fprintf( stderr, " %d", cmin ); /* */
-
- tryit:
- (void)SerGetBuf(refin, &count);
- SIOpb.ioParam.ioReqCount = count;
- if ( count >= cmin) {
- if ( count > cmax)
- SIOpb.ioParam.ioReqCount = (long) cmax;
- printmsg(4, "Read %ld", SIOpb.ioParam.ioReqCount);
- SIOpb.ioParam.ioRefNum = refin;
- SIOpb.ioParam.ioBuffer = (Ptr) cp;
- SIOpb.ioParam.ioPosMode = 0;
- PBRead (&SIOpb, FALSE);
- count = SIOpb.ioParam.ioActCount;
- #ifdef MULTIFINDER
- if (Ticks-Last_Check_Event >= MF_DELAY)
- if (Check_Events(0)) {
- if (Main_State == Abort_Program) {
- SIOClose(TRUE);
- exit(-1);
- }
- }
- #endif
- }
- else {
- #ifdef MULTIFINDER
- /* the data hasn't been received, ok to delay a bit */
- if (Ticks-Last_Check_Event >= MF_DELAY)
- if (Check_Events(sleepLimit)) {
- if (Main_State == Abort_Program) {
- SIOClose(TRUE);
- exit(-1);
- }
- }
- #endif
- count = 0;
- if (firstTry) {
- firstTry = FALSE;
- goto tryit;
- }
- }
-
-
- return( (int)count );
- }
-
-
- static ParamBlockRec pb = {0};
-
- int SIOWriteBusy()
- {
- if (pb.ioParam.ioResult == 1) {
- return TRUE;
- } else {
- return FALSE;
- }
- }
-
-
- int putu( c, count, refout )
- char *c;
- short count;
- short refout;
- {
- register ParmBlkPtr pbp = &pb;
- int spin;
- int isAsync;
-
- #ifdef DOASYNC
- isAsync = (asyncout != NULL) && (count <= BUFSIZE);
- if (isAsync) {
- spin = TRUE;
- do {
- if (async_pending == 0) {
- spin = FALSE;
- } else {
- pbp = &asyncout[async_tail].pb;
- if (pbp->ioParam.ioResult != 1) {
- async_pending --;
- async_tail = (async_tail + 1) % BUFFERS;
- } else {
- #ifdef MULTIFINDER
- if (Ticks-Last_Check_Event >= MF_DELAY)
- if (Check_Events(0))
- if (Main_State == Abort_Program) {
- SIOClose(TRUE);
- exit(-1);
- }
- #endif
- if (async_pending < BUFFERS) {
- spin = FALSE;
- }
- }
- }
- } while (spin);
-
- pbp = &asyncout[async_head].pb;
- memcpy(asyncout[async_head].buf, c, (long) count);
-
- pbp->ioParam.ioCompletion = NULL;
- pbp->ioParam.ioRefNum = refout;
- pbp->ioParam.ioBuffer = asyncout[async_head].buf;
- pbp->ioParam.ioReqCount = count;
- pbp->ioParam.ioPosMode = 0;
-
- PBWrite(pbp, TRUE);
-
- async_head = (async_head + 1) % BUFFERS;
- async_pending ++;
- } else {
- #endif
- pb.ioParam.ioCompletion = NULL;
- pb.ioParam.ioRefNum = refout;
- pb.ioParam.ioBuffer = c;
- pb.ioParam.ioReqCount = count;
- pb.ioParam.ioPosMode = 0;
-
- PBWrite(&pb, FALSE );
- #ifdef DOASYNC
- }
- #endif
-
- #ifdef MULTIFINDER
- if (Ticks-Last_Check_Event >= MF_DELAY)
- if (Check_Events(0))
- if (Main_State == Abort_Program) {
- SIOClose(TRUE);
- exit(-1);
- }
- #endif
-
- return( (short) pb.ioParam.ioActCount );
- }
-